using System.Web;
using FubuMVC.Core.Config;
using FubuMVC.Core.Results;
using FubuMVC.Core.Runtime;
using FubuMVC.Core.SessionState;
using Microsoft.Practices.ServiceLocation;
using FubuMVC.Core.Routing;
using FubuMVC.Core.Security;
using FubuMVC.Core.View;
using FubuMVC.Core.View.WebForms;
using FubuMVC.Core.Web.Security;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;

namespace FubuMVC.Container.StructureMap.Config
{
    public class FrameworkServicesRegistry : Registry
    {
        public FrameworkServicesRegistry()
        {
            ForRequestedType<IServiceLocator>()
                .AsSingletons()
                .TheDefault.Is.Object(new StructureMapServiceLocator());
            
            ForRequestedType<IOutputWriter>().TheDefault.Is.OfConcreteType<HttpResponseOutputWriter>();
            ForRequestedType<ICurrentRequest>().TheDefault.Is.OfConcreteType<CurrentRequest>();

            // TODO: Get this to work so that when there is no feedconvertor registered it will return the default
            // when no proper match is found
            ForRequestedType(typeof(IFeedConverterFor<>)).TheDefaultIsConcreteType(typeof(DefaultFeedConverter<>));
            //ForRequestedType<IFeedConverterFor<Object>>().TheDefault.Is.OfConcreteType<DefaultFeedConverter>();

            ForRequestedType<ISecurityContext>().TheDefault.Is.OfConcreteType<WebSecurityContext>();
            ForRequestedType<IAuthenticationContext>().TheDefault.Is.OfConcreteType<WebAuthenticationContext>();

            ForRequestedType<IViewRenderer>().TheDefault.Is.OfConcreteType<WebFormsViewRenderer>();

            ForRequestedType<HttpContextBase>().TheDefault.Is.ConstructedBy(ctx => new HttpContextWrapper(HttpContext.Current));

            ForRequestedType<IFlash>().TheDefault.Is.OfConcreteType<FlashProvider>();

            ForRequestedType<ICurrentResult>().CacheBy(InstanceScope.Hybrid).TheDefault.Is.OfConcreteType<CurrentRequestResultOverride>();

            //***  Can be replaced by DefaultConventionScanner
            //***  Left in here for now to make documentation easier later
            ForRequestedType<IRouteConfigurer>().AsSingletons().TheDefault.Is.OfConcreteType<RouteConfigurer>();
            ForRequestedType<IWebFormsControlBuilder>().TheDefault.Is.OfConcreteType<WebFormsControlBuilder>();
            ForRequestedType<IWebFormsViewRenderer>().TheDefault.Is.OfConcreteType<WebFormsViewRenderer>();
            ForRequestedType<IRequestDataProvider>().TheDefault.Is.OfConcreteType<RequestDataProvider>();
            ForRequestedType<ICurrentAction>().CacheBy(InstanceScope.Hybrid).TheDefault.Is.OfConcreteType<CurrentAction>();
            ForRequestedType<IRequestDictionaryHandler>().TheDefault.Is.OfConcreteType<RequestDictionaryHandler>();
            ForRequestedType<IDictionaryConverter>().TheDefault.Is.OfConcreteType<DictionaryConverter>();
            ForRequestedType<IModelState>().CacheBy(InstanceScope.Hybrid).TheDefaultIsConcreteType<ModelState>();
            //***  

            Scan(x =>
                {
                    x.TheCallingAssembly();
                    x.AssemblyContainingType<FrameworkServicesRegistry>();
                    
                    //NOTE: Currently disabled to ease documentation later, see above
                    //x.With<DefaultConventionScanner>();  
                });
        }
        // TODO: What is this for?
        public IRouteConfigurer routeConfigurer { get; private set; }
    }
}
